import React from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import uuid from 'uuid';

import {cloneDeep,} from 'lodash';

import {LoadingView} from '@folio/stripes/components';

import {getRecordObject} from '../../components/util';

import BookInStorageForm from './BookInStorageForm';

import {BASE_PAHT} from '../../constants';

function resourcesLoaded(obj, exceptions = []) {
  for (const resource in obj) {
    if (!exceptions.includes(resource)) {
      if (Object.prototype.hasOwnProperty.call(obj, resource)) {
        if (obj[resource] === null) {
          return false;
        }
        if (typeof obj[resource] === 'object') {
          if (Object.prototype.hasOwnProperty.call(obj[resource], 'isPending')) {
            if (obj[resource].isPending) {
              return false;
            }
          }
        }
      }
    }
  }
  return true;
}

class BookInStorageEdit extends React.Component {
  static propTypes = {
    resources: PropTypes.object,
    history: PropTypes.object,
    location: PropTypes.object,
    match: PropTypes.object,
    mutator: PropTypes.object,
  }

  getBookInStorage() {
    const { resources, match: { params: { id } } } = this.props;
    const selBookInStorage = (resources.selBookInStorage || {}).records || [];

    if (selBookInStorage.length === 0 || !id) return null;
    // Logging below shows this DOES sometimes find the wrong record. But why?
    // console.log(`getUser: found ${selUser.length} users, id '${selUser[0].id}' ${selUser[0].id === id ? '==' : '!='} '${id}'`);
    return selBookInStorage.find(u => u.id === id);
  }

  getBookInStorageFormValues() {
    const {
      resources,
      match,
    } = this.props;

    const today = moment().endOf('day');

    const initialFormValues = {
      inDate: today,
      status: 'editing',
    };

    if (!match.params.id) return initialFormValues;

    const bookInStorage = this.getBookInStorage();
    const bookInStorageFormValues = cloneDeep(bookInStorage);

    return {
      ...bookInStorageFormValues
    };
  }

  getBookInStorageFormData() {
    const {
      resources,
    } = this.props;
    const formData = getRecordObject(resources);

    return formData;
  }

  create = ({ requestPreferences, ...bookInStorageFormData }) => {
    const { mutator, history, location: { search } } = this.props;
    const bookInStorageData = cloneDeep(bookInStorageFormData);
    const bookInStorage = { ...bookInStorageData, id: uuid() };

    mutator.records.POST(bookInStorage)
      .then(() => {
        history.push(`${BASE_PAHT}/preview/${bookInStorage.id}${search}`);
      });
  }

  update({ requestPreferences, ...bookInStorageFormData }) {
    const {
      mutator,
      history,
      match: { params },
      location: {
        state,
        search,
      },
    } = this.props;

    const bookInStorage = cloneDeep(bookInStorageFormData);

    mutator.selBookInStorage.PUT(bookInStorage).then(() => {
      history.push({
        pathname: params.id ? `${BASE_PAHT}/preview/${params.id}` : BASE_PAHT,
        search,
        state,
      });
    });
  }

  render() {
    const {
      history,
      resources,
      location,
      match: { params },
    } = this.props;

    if (!resourcesLoaded(resources) || (!this.getBookInStorage() && this.props.match.params.id)) {
      return (
        <LoadingView
          data-test-form-page
          paneTitle={params.id ? '新建馆藏入库单' : '修改馆藏入库单'}
          defaultWidth="100%"
        />
      );
    }

    // data is information that the form needs, mostly to populate options lists
    const formData = this.getBookInStorageFormData();
    const onSubmit = params.id ? (record) => this.update(record) : (record) => this.create(record);

    return (
      <BookInStorageForm
        formData={formData}
        initialValues={this.getBookInStorageFormValues()} // values are strictly values...if we're editing (id param present) pull in existing values.
        onSubmit={onSubmit}
        onCancel={() => {
          history.push({
            pathname: params.id ? `${BASE_PAHT}/preview/${params.id}` : BASE_PAHT,
            state: location.state,
          });
        }}
        match={this.props.match}
        location={location}
        history={history}
      />
    );
  }
}

export default BookInStorageEdit;
